package com.ztesoft.web.taskgenerator.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ztesoft.core.cache.EhCacheService;
import com.ztesoft.core.common.Page;
import com.ztesoft.core.convert.IArgConversionService;
import com.ztesoft.core.idproduce.ISequenceGenerator;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.dao.DmDataStateDao;
import com.ztesoft.web.baseconfig.db.dao.DmPlanDao;
import com.ztesoft.web.baseconfig.db.po.DmDataStatePO;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.db.po.DmPlanRelationPO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.service.IDmPlanRelationService;
import com.ztesoft.web.baseconfig.service.IDmSrcTableService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.ShellCommandDefine;
import com.ztesoft.web.common.SubTableDefine;
import com.ztesoft.web.common.vo.HostConnInfoVO;
import com.ztesoft.web.common.vo.HostConnMethodVO;
import com.ztesoft.web.filecommon.db.dao.DmFDao;
import com.ztesoft.web.filecommon.db.dao.DmSrcFileDao;
import com.ztesoft.web.filecommon.db.dao.FileDirectoryDefineDao;
import com.ztesoft.web.filecommon.db.dao.FileObjServerRelDao;
import com.ztesoft.web.filecommon.db.dao.FileScanRuleInstanceDao;
import com.ztesoft.web.filecommon.db.po.DmFPO;
import com.ztesoft.web.filecommon.db.po.DmSrcFilePO;
import com.ztesoft.web.filecommon.db.po.FileDirectoryDefinePO;
import com.ztesoft.web.filecommon.db.po.FileObjServerRelPO;
import com.ztesoft.web.filecommon.db.po.FileScanRuleInstancePO;
import com.ztesoft.web.filecommon.service.IDmSrcFileService;
import com.ztesoft.web.filecommon.service.IFileDirectoryDefineService;
import com.ztesoft.web.filecommon.service.IFileScanRuleInstanceService;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskArg;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskArg.DmTaskCriteria;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskStageArg;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskDao;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskStageDao;
import com.ztesoft.web.taskgenerator.db.po.DmTaskPO;
import com.ztesoft.web.taskgenerator.db.po.DmTaskStagePO;
import com.ztesoft.web.taskgenerator.service.IDmTaskService;

/**
 * <Description> <br>
 * 
 * @author codeCreater<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2014年11月11日 <br>
 * @since V1.0<br>
 * @see com.ztesoft.web.taskgenerator.service.impl <br>
 */

@Service("dmTaskService")
public class DmTaskServiceImpl implements IDmTaskService {

	private static final ZTEsoftLogManager logger = ZTEsoftLogManager.getLogger(DmTaskServiceImpl.class);

	@Autowired
	private DmTaskDao dmTaskDao;

	@Autowired
	private DmPlanDao dmPlanDao;

	@Autowired
	private DmTaskStageDao dmTaskStageDao;

	@Autowired
	private IDmPlanRelationService dDmPlanRelationService;

	@Autowired
	private IDmSrcTableService iDmSrcTableService;

	@Autowired
	private SubTableDefine subTableDefine;

	@Autowired
	private DmDataStateDao dmDataStateDao;
	
	@Autowired
    private BaseInfoService baseInfoService;
	
	@Autowired
	private IDmSrcFileService iDmSrcFileService;
	
	@Autowired
	private IFileScanRuleInstanceService iFileScanRuleInstanceService;
	
	@Autowired
	private IFileDirectoryDefineService iFileDirectoryDefineService;
	
	@Autowired
	private DmFDao dmFDao;
	
	@Autowired
	private FileObjServerRelDao fileObjServerRelDao;
	
	@Autowired
	private FileDirectoryDefineDao fileDirectoryDefineDao;
	
	@Autowired
	private ShellCommandDefine shellCommandDefine;
	
	@Autowired
	private FileScanRuleInstanceDao fileScanRuleInstanceDao;

	@Autowired
	private DmSrcFileDao dmSrcFileDao;
	// 缓存内存
	@Resource(name = "frameworkEhCacheService")
	private EhCacheService dmsCacheService;

	/**
	 * 查询条件转换成Arg类的服务接口
	 */
	@Resource(name = "defaultArgConversionService")
	private IArgConversionService argConversionService;

	/**
	 * 主键生成器
	 */
	@Resource(name = "sequenceProcGenerator")
	private ISequenceGenerator sequenceGenerator;

	@Override
	public DmTaskPO selectByPrimaryKey(Integer key) throws BaseAppException {
		return dmTaskDao.selectByPrimaryKey(key);
	}

	@Override
	public List<DmTaskPO> selectByArg(DmTaskPO record) throws BaseAppException {
		logger.debug("selectByArg begin...record={0}", record);
		DmTaskArg arg = argConversionService.invokeArg(DmTaskArg.class, record);
		return dmTaskDao.selectByArg(arg);
	}

	@Override
	public Page<DmTaskPO> selectByArgAndPage(DmTaskPO record, Page<DmTaskPO> resultPage) throws BaseAppException {
		logger.debug("selectByArgAndPage begin...record={0}", record);
		DmTaskArg arg = argConversionService.invokeArg(DmTaskArg.class, record);
		resultPage = dmTaskDao.selectByArgAndPage(arg, resultPage);
		return resultPage;
	}

	@Override
	public int add(DmTaskPO record) throws BaseAppException {
		logger.debug("add begin...record={0}", record);
		return dmTaskDao.insertSelective(record);

	}

	@Override
	public int update(DmTaskPO record) throws BaseAppException {
		logger.debug("update begin...record={0}", record);
		return dmTaskDao.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(DmTaskPO record) throws BaseAppException {
		logger.debug("delete begin...record={0}", record);
		return dmTaskDao.deleteByPrimaryKey(record.getDmTaskId());
	}

	@Override
	public int countByArg(Integer dmPlanId, Integer groupNbr) throws BaseAppException {
		logger.debug("add begin...record={0}", dmPlanId);
		DmTaskArg arg = new DmTaskArg();
		DmTaskCriteria criteria = arg.createCriteria();
		arg.setCountsql1("SELECT count(DM_TASK_ID) FROM DM_TASK ");
		criteria.andDmPlanIdEqualTo(dmPlanId);
		criteria.andGroupNbrEqualTo(groupNbr);
		List<Integer> list = dmTaskDao.countByArg(arg);
		return list.get(0);
	}

	@Override
	public List<DmTaskPO> selectByDmTaskInfo(Integer dmPlanId, Integer groupNbr) throws BaseAppException {
		logger.debug("\r\n|查询一次|" + dmPlanId);
		return dmTaskDao.selectByDmTaskInfo(dmPlanId, groupNbr);
	}

	@Override
	public List<DmTaskPO> selectByTaskInfoNotState(Integer dmPlanId, Integer groupNbr) throws BaseAppException {
		logger.debug("\r\n|取任务的最大执行时间|" + dmPlanId);
		return dmTaskDao.selectByTaskInfoNotState(dmPlanId, groupNbr);
	}

	@Override
	public int addBatch(List<DmTaskPO> dtLst) throws BaseAppException {
		logger.debug("批量新增任务表记录start", dtLst);
		int result;
		List<DmTaskPO> lstBatch = new ArrayList<DmTaskPO>();
		List<DmTaskStagePO> lstStageBatch = null;
		/*
		 * 1、1批量新增任务
		 */
		for (DmTaskPO dmTaskPO : dtLst) {
			setDmTaskPOInfo(dmTaskPO);
			lstBatch.add(dmTaskPO);
		}
		result = dmTaskDao.insertBatch(lstBatch);
		/*
		 * 1、2添加任务环节~
		 */
		List<DmPlanRelationPO> relaPOLst = null;
		DmSrcTablePO srcTable = null;
		for (DmTaskPO dmTaskPO : lstBatch) {
			
			if(DMSConstant.SOURCE_TYPE_TABLE == dmTaskPO.getSourceType()){
				result = generateStageTable(dmTaskPO);//生成数据库表数据
			}else if(DMSConstant.SOURCE_TYPE_FILE == dmTaskPO.getSourceType()){
				result = generateStageFile(dmTaskPO); //生成文件数据
			}
		}
		logger.debug("批量新增任务表记录end");
		return result;
	}
	
	private int generateStageFile(DmTaskPO dmTaskPO) throws BaseAppException {
		int result = 0;
		List<DmTaskStagePO> lstStageBatch;
		List<DmPlanRelationPO> relaPOLst;
		DmSrcFilePO srcFile;
	
		// 查询策略 ，根据计划标识和组号获取有效策略，循环策略创建任务环节记录
		relaPOLst = dDmPlanRelationService.selectByPlanIdAndGroupNbr(dmTaskPO.getDmPlanId(), dmTaskPO.getGroupNbr());
		for (DmPlanRelationPO relaPO : relaPOLst) {
			srcFile = iDmSrcFileService.selectBydmStrategyId(relaPO.getDmStrategyId());// 根据策略获取对象信息
			if (srcFile != null) {
				int dmStrategyId = relaPO.getDmStrategyId();
				int sourceDataId = srcFile.getSourceDataId();
				//生成dm_f_策略id和dm_f_detal_策略id表
				createTableDM(dmStrategyId);
				//批量生成任务环节表和轨迹表数据
				lstStageBatch = new ArrayList<DmTaskStagePO>();
				lstStageBatch = setStageTableInfo(dmTaskPO, sourceDataId, dmStrategyId, getTableName(sourceDataId));
				dmTaskStageDao.insertBatch(lstStageBatch);
			}
		}
		return result;
	}
	/**
	 * 文件脚本轨迹表
	 * @param dmInfoId
	 * @param directoryId
	 * @param scanRuleId
	 * @param sourceDataId
	 * @param dmStrategyId
	 * @param dmTaskPO
	 * @throws BaseAppException
	 */
	private void addDmFStrategy(int dmInfoId, int directoryId, int scanRuleId, int sourceDataId, 
			int dmStrategyId, DmTaskPO dmTaskPO) throws BaseAppException{
		List<DmFPO> dmFList = new ArrayList<DmFPO>();
		DmFPO dmF;
		int dmPlanId = dmTaskPO.getDmPlanId();
		DmPlanPO dplan = dmPlanDao.selectByPrimaryKey(dmPlanId);
		int nodeId = dplan.getNodeId();
		List<FileObjServerRelPO> fosList = fileObjServerRelDao.selectByObjId(sourceDataId);//文件对象主机关联表
		FileDirectoryDefinePO fdd = fileDirectoryDefineDao.selectByPrimaryKey(directoryId);//目录表达式
		FileScanRuleInstancePO fsr = fileScanRuleInstanceDao.selectByPrimaryKey(scanRuleId);//表达式变量映射关系表
		DmSrcFilePO dsf = dmSrcFileDao.selectByPrimaryKey(sourceDataId);
		List<String> pathList = getPathExp(fdd.getSourceXpath(), fdd.getDirOrder(), sourceDataId, dmPlanId, nodeId, 0);//源目录规则
		List<String> pathTargetExpList = getPathExp(fdd.getTargetXpath(), fdd.getDirOrder(), sourceDataId, dmPlanId, nodeId, 1);//目标目录规则
		List<String> scanRuleList = getPathExp(fsr.getFilenameScanXpath(), fsr.getDirOrder(), sourceDataId, dmPlanId, nodeId, 2);//检索规则
		int pkId;
		for (int i=0; i<pathList.size();i++) {
			for (int j = 0; j < fosList.size(); j++) {
				FileObjServerRelPO fos = fosList.get(j);
				dmF = new DmFPO();
				pkId = sequenceGenerator.sequenceIntValue("DM_F", "TRACK_ID");
				dmF.setTrackId(pkId);
				dmF.setDmInfoId(dmInfoId);
				dmF.setDmTaskId(dmTaskPO.getDmTaskId());
				dmF.setSourceDataId(sourceDataId);
				dmF.setDmStrategyId(dmStrategyId);
				dmF.setDmBackupType(dsf.getDmBackupType());
				dmF.setSrcIp(fos.getSrcIp());
				dmF.setSrcUser(getUserName(fos.getSrcHostId()));
				dmF.setSrcPath(pathList.get(i));
				if(dplan.getOperType()==0){
					dmF.setTargetIp(fos.getDestIp());
					dmF.setTargetUser(getUserName(fos.getDestHostId()));
					dmF.setTargetPath(pathTargetExpList.get(i));
				}
				dmF.setShellScript("find " + pathList.get(i) + " " + Utils.convertIdList2StringBy(scanRuleList, " -o ", 3));
				setDmFInfo(dmF);
				dmFList.add(dmF);
			}
		}

		dmFDao.insertBatch("DM_F_"+dmStrategyId, dmFList);
	}
	//

	private void setDmFInfo(DmFPO dmF) {
		dmF.setTotalRecordCount(0);
		dmF.setCheckDataCount(0);
		dmF.setTotalRecordSize(java.math.BigDecimal.ZERO);
		dmF.setCheckDataSize(java.math.BigDecimal.ZERO);
		dmF.setCreateDate(new Date());
		dmF.setState("00T");
		dmF.setStateDate(new Date());
	}
	/**
	 * 获取目录表达式
	 * @param processStr  待处理的目录表达式
	 * @param sourceDataId
	 * @param dmPlanId
	 * @param nodeId
	 * @param dataTpye 0 源目录 1 目标目录 2 检索表达式
	 * @return
	 */
	private List<String> getPathExp(String processStr, int dirOrder, int sourceDataId, int dmPlanId, int nodeId,int dataTpye){
		List<String> pathList = new ArrayList<String>();
		pathList = shellCommandDefine.initFileName(processStr, dirOrder, sourceDataId, nodeId, dmPlanId, dataTpye);
		return pathList;
	}	/**
	 * 獲取主機用戶
	 * @param hostId
	 * @return
	 */
	private String getUserName(Integer hostId){
		String userName = "";
		 HostConnMethodVO vo = null;
			Map<String, HostConnMethodVO> connMethodMap = null;// 主机连接信息
			connMethodMap = new HashMap<String, HostConnMethodVO>();
			try {
				HostConnInfoVO hostConnInfoVO = baseInfoService.queryHostConn(hostId);
				 List<HostConnMethodVO> hostConnMethodList = hostConnInfoVO.getHostConnMethod();
				 for (HostConnMethodVO vos : hostConnMethodList) {
						connMethodMap.put(vos.getConnMethod().toLowerCase(), vos);
				}
				vo =  connMethodMap.get(DMSConstant.HOST_LINK_TELNET);
				userName = vo.getUserName();
			} catch (BaseAppException e) {
				logger.debug(e);
			}
			return userName ;
	}
	private void createTableDM(int dmStrategyId) {
		String tbName = "DM_F_"+String.valueOf(dmStrategyId);
		createTable(tbName, "DM_F");
		String tbDetailName = "DM_F_DETAIL_" + String.valueOf(dmStrategyId);
		createTable(tbDetailName, "DM_F_DETAIL");
	}

	private void createTable(String tbName, String srcTableName) {
		int count = dmTaskDao.selectExistTableName(tbName);
		if (count == 0) {// 创建一张dm_tableName表
			dmTaskDao.addCreateDmTable(tbName, srcTableName);
		}
	}
	/**
	 * 生成任务环节表
	 * @param dmTaskPO
	 * @param sourceDataId
	 * @param dmStrategyId
	 * @param tableName
	 * @param dataTableName
	 * @return
	 */
	private List<DmTaskStagePO> setStageTableInfo(DmTaskPO dmTaskPO,
			int sourceDataId,  int dmStrategyId, List<String> tableNameList) {
		List<DmTaskStagePO> lstStageBatchList = new ArrayList<DmTaskStagePO>();
		String[] objArr = null;
		for (String tableName : tableNameList) {
			List<DmTaskStagePO> lstStageBatch = new ArrayList<DmTaskStagePO>();
			objArr = tableName.split(":");
			DmTaskStagePO dmTaskStagePO = new DmTaskStagePO();
			dmTaskStagePO.setDmStrategyId(dmStrategyId);
			dmTaskStagePO.setSourceDataId(sourceDataId);
			dmTaskStagePO.setCheckObjName(objArr[0]+" "+ objArr[2]);
			dmTaskStagePO.setNodeId(dmTaskPO.getNodeId());
		
			//生成任务环节表
			lstStageBatch = getBatchLst(dmTaskStagePO, dmTaskPO);
			Integer dmInfoId = lstStageBatch.get(0).getDmInfoId();
			lstStageBatchList.addAll(lstStageBatch);
			
			//生成轨迹表
			String directoryId = objArr[1];
			String scanRuleId = objArr[3];
			
			
			try {
				addDmFStrategy(dmInfoId, Integer.valueOf(directoryId), Integer.valueOf(scanRuleId), sourceDataId, 
						dmStrategyId, dmTaskPO);
			} catch (NumberFormatException e) {
				logger.debug(e);
			} catch (BaseAppException e) {
				logger.debug(e);
			}
		}
		return lstStageBatchList;
	}
	/*
	 * 任务环节表对象名获取 
	 */
	private List<String> getTableName(int sourceDataId) throws BaseAppException{
		//i.	根据对象ID提取FILE_SCAN_RULE_INSTANCE表记录
		//ii.	根据对象ID提取FILE_DIRECTORY_DEFINE表记录
		List<FileScanRuleInstancePO> insList = new ArrayList<FileScanRuleInstancePO>();
		List<FileDirectoryDefinePO> defineList = new ArrayList<FileDirectoryDefinePO>();
		List<String> objNameList = new ArrayList<String>();
		insList = iFileScanRuleInstanceService.selectPOBySourceDataId(sourceDataId);
		defineList = iFileDirectoryDefineService.selectPOBySourceDataId(sourceDataId);
		objNameList = cross(getSourceXpathList(defineList), getFileScanRuleList(insList));
		return objNameList;
	}
	/**
	 * 记录数求笛卡尔积
	 * 对象名就是由FILE_DIRECTORY_DEFINE.source_xpath和FILE_SCAN_RULE_INSTANCE.filename_scan_xpath拼接而成
	 * @param list1
	 * @param list2
	 * @return
	 */
	private List<String> cross(List<String> list1, List<String> list2){
		List<String> crossList = new ArrayList<String>();
		for(int i=0; i<list1.size();i++){
			for (int j=0;j<list2.size();j++) {
				crossList.add(list1.get(i)+":"+list2.get(j));
			}
		}
		return crossList;
	}
	/**
	 * FILE_SCAN_RULE_INSTANCE.filename_scan_xpath
	 * @param insList
	 * @return
	 */
	private List<String> getFileScanRuleList(List<FileScanRuleInstancePO> insList){
		List<String> insStrList = new ArrayList<String>();
		if(Utils.notEmpty(insList)){
			for (FileScanRuleInstancePO fileScanRuleInstancePO : insList) {
				insStrList.add(fileScanRuleInstancePO.getFilenameScanXpath()+":"+fileScanRuleInstancePO.getScanRuleId());
			}
		}
		return insStrList;
	}
	/**
	 * FILE_DIRECTORY_DEFINE.source_xpath
	 * @param defineList
	 * @return
	 */
	private List<String> getSourceXpathList(List<FileDirectoryDefinePO> defineList){
		List<String> defineStrList = new ArrayList<String>();
		if(Utils.notEmpty(defineList)){
			for (FileDirectoryDefinePO fileDirectoryDefinePO : defineList) {
				defineStrList.add(fileDirectoryDefinePO.getSourceXpath()+":"+fileDirectoryDefinePO.getDirectoryId());
			}
		}
		return defineStrList;
	}

	private int generateStageTable(DmTaskPO dmTaskPO)
			throws BaseAppException {
		int result =0;
		List<DmTaskStagePO> lstStageBatch;
		List<DmPlanRelationPO> relaPOLst;
		DmSrcTablePO srcTable;
		relaPOLst = dDmPlanRelationService.selectByPlanIdAndGroupNbr(dmTaskPO.getDmPlanId(), dmTaskPO.getGroupNbr());
		String dataTableName = "";
		DmTaskStagePO dmTaskStagePO;
		StringBuilder sb;
		for (DmPlanRelationPO relaPO : relaPOLst) {
			srcTable = iDmSrcTableService.selectBydmStrategyId(relaPO.getDmStrategyId());// 根据策略获取对象信息
			sb = new StringBuilder();
			if (srcTable != null) {
				lstStageBatch = new ArrayList<DmTaskStagePO>();
				if ("0".equals(srcTable.getSubFlag())) {// 不是分表
					logger.info("自动生成单表[{0}]任务环节~", srcTable.getTableName());
					// 根据分表名和任务环节生成任务环节记录表
					dmTaskStagePO = new DmTaskStagePO();
					dmTaskStagePO.setDmStrategyId(relaPO.getDmStrategyId());
					dmTaskStagePO.setSourceDataId(srcTable.getSourceDataId());
					dmTaskStagePO.setCheckObjName(srcTable.getTableName());
					dmTaskStagePO.setNodeId(dmTaskPO.getNodeId());
					lstStageBatch = getBatchLst(dmTaskStagePO, dmTaskPO);
					// 判断表名是否存在，如果存在则不做创建表动作，不存在再创建一张(DM_表名)的体检结果明细表
					dataTableName = sb.append("DM_").append(srcTable.getTableName()).toString().toLowerCase();
					int count = dmTaskDao.selectExistTableName(dataTableName);
					if (count == 0) {// 创建一张dm_tableName表
						dmTaskDao.addCreateDmTable(dataTableName, "DM");
					}
				} else {// 是分表
					List<String> tableNameLst = subTableDefine.initTableName(srcTable, dmTaskPO.getNodeId(),
							relaPO.getDmPlanId());
					logger.info("生成分表[{0}]任务环节~", tableNameLst);
					for (String tableNameStr : tableNameLst) {
						dmTaskStagePO = new DmTaskStagePO();
						dmTaskStagePO.setDmStrategyId(relaPO.getDmStrategyId());
						dmTaskStagePO.setSourceDataId(srcTable.getSourceDataId());
						dmTaskStagePO.setCheckObjName(tableNameStr);
						dmTaskStagePO.setNodeId(dmTaskPO.getNodeId());
						lstStageBatch.addAll(getBatchLst(dmTaskStagePO, dmTaskPO));
						logger.debug("要插入的任务环节表记录：" + lstStageBatch.size());
						int count = dmTaskDao.selectExistTableName("DM_" + tableNameStr);
						logger.debug("DM_" + tableNameStr + "表在数据库表存在||", count);
						if (count == 0) {
							// 创建一张dm_tableName表
							dmTaskDao.addCreateDmTable("DM_" + tableNameStr, "DM");
							logger.debug("DM_" + tableNameStr + "表创建成功");
						}
					}
				}
				result = dmTaskStageDao.insertBatch(lstStageBatch);
			}
		}
		return result;
	}

	private void setDmTaskPOInfo(DmTaskPO dmTaskPO) throws BaseAppException {
		int pkId = sequenceGenerator.sequenceIntValue("DM_TASK", "DM_TASK_ID");
		dmTaskPO.setDmTaskId(pkId);
		dmTaskPO.setStateDate(new Date());
		dmTaskPO.setCreateDate(new Date());
		dmTaskPO.setParentTaskId(null);
		dmTaskPO.setStartTime(null);
		dmTaskPO.setEndTime(null);
		dmTaskPO.setErrorDesc(null);
		dmTaskPO.setNeedSubtask(DMSConstant.NEED_SUBTASK_F);
		dmTaskPO.setState(DMSConstant.Status.PENDING.toString());// 待执行
	}

	/**
	 * 按操作类型的值生成任务环节表 0--体检&备份&清理 1--体检&直接清理 2--体检
	 * 
	 * @param dmTaskStagePO
	 * @param dmTaskPO
	 * @return
	 */
	private List<DmTaskStagePO> getBatchLst(DmTaskStagePO dmTaskStagePO, DmTaskPO dmTaskPO) {
		List<DmTaskStagePO> dtsLst = new ArrayList<DmTaskStagePO>();
		Integer result = 0;
		Integer operType = dmTaskPO.getOperType();
		if (operType == 0) {
			result = 3;
		} else if (operType == 1) {
			result = 2;
		} else if (operType == 2) {
			result = 1;
		}
		if (result == 2) {
			for (int i = 0; i <= result; i += 2) {
				DmTaskStagePO dts = dmTaskStagePO.cloneBO();
				getDmTaskStageInfo(dmTaskPO, dts);
				dts.setStage(i);
				dtsLst.add(dts);
			}
		} else {
			for (int i = 0; i < result; i++) {
				DmTaskStagePO dts = dmTaskStagePO.cloneBO();
				getDmTaskStageInfo(dmTaskPO, dts);
				dts.setStage(i);
				dtsLst.add(dts);
			}
		}
		return dtsLst;
	}
	/**
	 * 任务环节表设置
	 * 
	 * @param dmTaskPO
	 * @param dts
	 */
	private void getDmTaskStageInfo(DmTaskPO dmTaskPO, DmTaskStagePO dts) {
		int pkId;
		try {
			pkId = sequenceGenerator.sequenceIntValue("DM_TASK_STAGE", "DM_INFO_ID");
			dts.setDmInfoId(pkId);
			dts.setDmTaskId(dmTaskPO.getDmTaskId());
			dts.setDataType(dmTaskPO.getSourceType());
			dts.setNodeId(dmTaskPO.getNodeId());
			dts.setIsCheck(dmTaskPO.getIsCheck());
			dts.setState(DMSConstant.Status.PENDING.toString());
			dts.setStateDate(new Date());
			dts.setCreateDate(new Date());
			dts.setErrorDesc(null);
		} catch (BaseAppException e) {
			logger.debug("/r/n|异常|", e);
		}
	}

	@Override
	public List<DmTaskPO> selectByNeedSubtask() throws BaseAppException {
		return dmTaskDao.selectByNeedSubtask();
	}

	/**
	 * 根据计划的是否需要审核判断任务表的审核状态值
	 * 
	 * @param dmPlan
	 * @return
	 */
	private Integer getNeedCheckInfo(DmPlanPO dmPlan) {

		Integer needCheck;
		// 是否审核通过
		if ("T".equalsIgnoreCase(dmPlan.getNeedCheck())) {// T需要确认==待审核,F不需要确认==审核通过
			needCheck = DMSConstant.IS_CHECK_DEALPASS;
		} else {
			needCheck = DMSConstant.IS_CHECK_PASS;
		}

		return needCheck;
	}

	@Override
	public int addSubBatch(List<DmTaskPO> dtLst) throws BaseAppException {
		logger.debug("系统批量新增子任务表记录start{0}", dtLst);
		// 批量新增任务
		int result;
		DmPlanPO dmPlanPO;
		List<DmTaskStagePO> stageLst = new ArrayList<DmTaskStagePO>();
		List<DmTaskStagePO> lstStageBatch = new ArrayList<DmTaskStagePO>();
		DmTaskArg art = new DmTaskArg();
		DmTaskPO po = new DmTaskPO();
		for (DmTaskPO dmTaskPO : dtLst) {
			dmPlanPO = dmPlanDao.selectByPrimaryKey(dmTaskPO.getDmPlanId());
			int pkId = sequenceGenerator.sequenceIntValue("DM_TASK", "DM_TASK_ID");
			dmTaskPO.setDmTaskId(pkId);
			dmTaskPO.setStateDate(new Date());
			dmTaskPO.setCreateDate(new Date());
			dmTaskPO.setStartTime(null);
			dmTaskPO.setEndTime(null);
			dmTaskPO.setErrorDesc(null);
			dmTaskPO.setIsCheck(getNeedCheckInfo(dmPlanPO));
			dmTaskPO.setNeedSubtask(DMSConstant.NEED_SUBTASK_F);
			dmTaskPO.setState(DMSConstant.Status.PENDING.toString());// 待执行
			result = dmTaskDao.insert(dmTaskPO);

			// 更新母任务实例表
			dmTaskDao.updateByNeedSubTask(dmTaskPO.getParentTaskId());

			// DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
			// taskd.andDmTaskIdEqualTo(dmTaskPO.getParentTaskId());
			// po.setEndTime(new Date());
			// po.setStateDate(new Date());
			// po.setNeedSubtask("F");
			// dmTaskDao.updateByArgSelective(po, art);

			// 查询母任务下的所有任务环节表记录
			stageLst = dmTaskStageDao.selectByTaskId(dmTaskPO.getParentTaskId());
			for (DmTaskStagePO dmTaskStagePO : stageLst) {
				int dmInfoId = sequenceGenerator.sequenceIntValue("DM_TASK_STAGE", "DM_INFO_ID");
				dmTaskStagePO.setDmInfoId(dmInfoId);
				dmTaskStagePO.setDmTaskId(dmTaskPO.getDmTaskId());
				dmTaskStagePO.setNodeId(dmTaskPO.getNodeId());
				dmTaskStagePO.setState(DMSConstant.Status.PENDING.toString());// 00T
				dmTaskStagePO.setIsCheck(dmTaskPO.getIsCheck());
				dmTaskStagePO.setTaskStartTime(null);
				dmTaskStagePO.setTaskEndTime(null);
				dmTaskStagePO.setCheckCount(0);
				dmTaskStagePO.setTotalRecordCount(0);
				dmTaskStagePO.setCheckDataSize(null);
				dmTaskStagePO.setTotalDataSize(null);
				dmTaskStagePO.setCheckDate(null);
				dmTaskStagePO.setErrorDesc(null);
				lstStageBatch.add(dmTaskStagePO);
			}
		}
		result = dmTaskStageDao.insertBatch(lstStageBatch);
		logger.debug("系统批量新增子任务表记录end");
		return result;
	}

	private Integer getPriorityInfo(DmPlanPO dmPlan) {
		Integer priority;
		if (DMSConstant.EXEC_TYPE_AUTO.equals(dmPlan.getExecType())) {// 若计划为自动执行，则填为2；
			priority = DMSConstant.PRIORITY_AUTO;
		} else {// 若计划为手工执行，则填为1；
			priority = DMSConstant.PRIORITY_HAND;
		}
		return priority;
	}

	@Override
	public int addCreateHandTask(Integer dmTaskId) throws BaseAppException {
		logger.debug("手工任务批量新增", dmTaskId);

		List<DmTaskStagePO> lstStageBatch;
		DmTaskPO taskPO = dmTaskDao.selectByPrimaryKey(dmTaskId);
		DmPlanPO dmPlanPO = dmPlanDao.selectByPrimaryKey(taskPO.getDmPlanId());
		int result;
		DmTaskPO dmTaskPO = setDmTaskPOInfo(taskPO, dmPlanPO);
		result = dmTaskDao.insert(dmTaskPO);
		// 更新母任务实例表
		dmTaskDao.updateByNeedSubTask(dmTaskId);
		// 查询策略 ，根据计划标识和组号获取有效策略，循环策略创建任务环节记录
		List<DmPlanRelationPO> relaPOLst = dDmPlanRelationService.selectByPlanIdAndGroupNbr(dmTaskPO.getDmPlanId(),
				dmTaskPO.getGroupNbr());
		Integer dmStrategyId = null;
		for (DmPlanRelationPO relaPO : relaPOLst) {
			dmStrategyId = relaPO.getDmStrategyId();
			if(1==dmPlanPO.getSourceType()){
				lstStageBatch = addTableForStage(dmPlanPO, dmTaskPO, dmStrategyId, relaPO);
			}else{
				lstStageBatch = addFileForStage(dmPlanPO, dmTaskPO, dmStrategyId, relaPO);
			}
			result = dmTaskStageDao.insertBatch(lstStageBatch);
			}
		return result;
	}
	/**
	 * 初始化任务表
	 * @param taskPO
	 * @param dmPlanPO
	 * @return
	 * @throws BaseAppException
	 */
	private DmTaskPO setDmTaskPOInfo(DmTaskPO taskPO, DmPlanPO dmPlanPO)
			throws BaseAppException {
		DmTaskPO dmTaskPO = new DmTaskPO();
		int pkId = sequenceGenerator.sequenceIntValue("DM_TASK", "DM_TASK_ID");
		dmTaskPO.setDmTaskId(pkId);
		dmTaskPO.setDmPlanId(taskPO.getDmPlanId());
		dmTaskPO.setGroupNbr(taskPO.getGroupNbr());
		dmTaskPO.setSourceType(dmPlanPO.getSourceType());
		dmTaskPO.setName(getTaskName(taskPO));
		dmTaskPO.setNodeId(dmPlanPO.getNodeId());
		dmTaskPO.setPriority(getPriorityInfo(dmPlanPO));
		dmTaskPO.setIsCheck(getNeedCheckInfo(dmPlanPO));
		dmTaskPO.setOperType(dmPlanPO.getOperType());
		dmTaskPO.setParentTaskId(null);
		dmTaskPO.setScheduleDate(new Date());
		dmTaskPO.setStateDate(new Date());
		dmTaskPO.setCreateDate(new Date());
		dmTaskPO.setStartTime(null);
		dmTaskPO.setEndTime(null);
		dmTaskPO.setErrorDesc(null);
		dmTaskPO.setNeedSubtask(DMSConstant.NEED_SUBTASK_F);
		dmTaskPO.setState(DMSConstant.Status.PENDING.toString());// 待执行
		return dmTaskPO;
	}
/**
 * 环节表-表
 * @param dmPlanPO
 * @param dmTaskPO
 * @param dmStrategyId
 * @param relaPO
 * @return
 * @throws BaseAppException
 */
	private List<DmTaskStagePO> addTableForStage(DmPlanPO dmPlanPO,
		DmTaskPO dmTaskPO, Integer dmStrategyId, DmPlanRelationPO relaPO) throws BaseAppException {
		// 根据策略获取对象信息
		DmSrcTablePO srcTable = iDmSrcTableService.selectBydmStrategyId(dmStrategyId);
		List<DmTaskStagePO> lstStageBatch =null;
		String tableName;
		String dataTableName;
		DmTaskStagePO dmTaskStagePO;
		if (srcTable != null) {
			if ("0".equals(srcTable.getSubFlag())) {// 不是分表
				lstStageBatch = new ArrayList<DmTaskStagePO>();
				tableName = srcTable.getTableName();
				// 根据分表名和任务环节生成任务环节记录表
				dmTaskStagePO = new DmTaskStagePO();
				dmTaskStagePO.setDmStrategyId(dmStrategyId);
				dmTaskStagePO.setSourceDataId(srcTable.getSourceDataId());
				dmTaskStagePO.setCheckObjName(tableName);
				dmTaskStagePO.setNodeId(dmPlanPO.getNodeId());
				lstStageBatch = getBatchLst(dmTaskStagePO, dmTaskPO);
				// 判断表名是否存在，如果存在则不做创建表动作，不存在再创建一张(DM_表名)的体检结果明细表
				dataTableName = "DM_"+tableName;
				int count = dmTaskDao.selectExistTableName(dataTableName);
				if (count == 0) {
					// 创建一张dm_tableName表
					dmTaskDao.addCreateDmTable(dataTableName, "DM");
				}
			} else {// 是分表
				lstStageBatch = new ArrayList<DmTaskStagePO>();
				List<String> tableNameLst = subTableDefine.initTableName(srcTable, dmTaskPO.getNodeId(),
						relaPO.getDmPlanId());
				for (String tableNameStr : tableNameLst) {
					dmTaskStagePO = new DmTaskStagePO();
					dmTaskStagePO.setDmStrategyId(dmStrategyId);
					dmTaskStagePO.setSourceDataId(srcTable.getSourceDataId());
					dmTaskStagePO.setCheckObjName(tableNameStr);
					dmTaskStagePO.setNodeId(dmTaskPO.getNodeId());
					lstStageBatch.addAll(getBatchLst(dmTaskStagePO, dmTaskPO));
					logger.debug("要插入的任务环节表记录：" + lstStageBatch.size());
					int count = dmTaskDao.selectExistTableName("DM_" + tableNameStr);
					logger.debug("DM_" + tableNameStr + "表在数据库表存在||", count);
					if (count == 0) {
						// 创建一张dm_tableName表
						dmTaskDao.addCreateDmTable("DM_" + tableNameStr, "DM");
						logger.debug("DM_" + tableNameStr + "表创建成功");
					}
				}
			}
		}
		return lstStageBatch;
	}
	/**
	 * 环节表-文件
	 * @param dmPlanPO
	 * @param dmTaskPO
	 * @param dmStrategyId
	 * @param relaPO
	 * @return
	 * @throws BaseAppException
	 */
	private List<DmTaskStagePO> addFileForStage(DmPlanPO dmPlanPO,
			DmTaskPO dmTaskPO, Integer dmStrategyId, DmPlanRelationPO relaPO) throws BaseAppException {
		DmSrcFilePO srcFile = iDmSrcFileService.selectBydmStrategyId(relaPO.getDmStrategyId());// 根据策略获取对象信息
		List<DmTaskStagePO> lstStageBatch = null;
		if (srcFile != null) {
			int sourceDataId = srcFile.getSourceDataId();
			//生成dm_f_策略id和dm_f_detal_策略id表
			createTableDM(dmStrategyId);
			//批量生成任务环节表和轨迹表数据
			lstStageBatch = new ArrayList<DmTaskStagePO>();
			lstStageBatch = setStageTableInfo(dmTaskPO, sourceDataId, dmStrategyId, getTableName(sourceDataId));
		}	
		return lstStageBatch;
		}
	/**
	 * 包装任务名称
	 * DM_PLAN.plan_name_日期_DM_PLAN_RELATION.group_nbr_派生_序号，第一次派生序号为1，之后递增
	 * 
	 * @param dmTaskPO
	 * @return
	 */
	private String getTaskName(DmTaskPO dmTaskPO) {
		StringBuffer sbName = new StringBuffer();// StingBuffer用于存放任务周期名称
		int len;
		String taskName;
		SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.STR_DATE_FORMAT_DAY_WITHOUT_SPLIT);// yyyy-MM
		String s = Arrays.toString(dmTaskPO.getName().split("-"));
		Pattern p = Pattern.compile("手工");
		Matcher m = p.matcher(s);
		if (m.find()) {
			len = Integer.valueOf(dmTaskPO.getName().substring(dmTaskPO.getName().lastIndexOf("-") + 1)) + 1;
		} else {
			len = 1;
		}
		taskName = sbName.append(dmTaskPO.getName().split("-")[0]).append("-").append(sdf.format(new Date()))
				.append("-").append(dmTaskPO.getGroupNbr()).append("-").append("手工").append("-").append(len).toString();
		return taskName;
	}

	@Override
	public int selectCountByArg(DmTaskArg arg) throws BaseAppException {
		return dmTaskDao.countByArg(arg).get(0);
	}

	@Override
	public DmPlanPO changeTime(Integer dmPlanId) throws BaseAppException {
		DmTaskPO dmPo = dmTaskDao.changeTime(dmPlanId);
		DmPlanPO dpPO = dmPlanDao.selectByPrimaryKey(dmPlanId);
		if (dmPo.getExpDate().before(dmPo.getSysDate())) {// 过了失效时间
			dpPO.setIsChange(0);
		}
		return dpPO;
	}

	@Override
	public Map<String, Object> hasRunningTask(Integer dmPlanId) throws BaseAppException {
		// 除非有“待执行且已处理了部分数据”或执行中或失败的任务，否则计划是可以进行修改的
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("success", true);
		DmTaskArg arg = new DmTaskArg();
		DmTaskCriteria criteria = arg.createCriteria();
		criteria.andDmPlanIdEqualTo(dmPlanId);
		List<DmTaskPO> list = dmTaskDao.selectByArg(arg);
		for (DmTaskPO dmTaskPO : list) {
			if (DMSConstant.Status.PROCESSING.toString().equals(dmTaskPO.getState())) {
				result.put("success", false);
				result.put("info", "该计划下有任务正在执行，不能编辑！");
			} else if (DMSConstant.Status.FALSE.toString().equals(dmTaskPO.getState())) {
				result.put("success", false);
				result.put("info", "该计划下有执行失败的任务，不能编辑！");
			} else if (!Utils.isEmpty(dmTaskPO.getParentTaskId())
					&& DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())) {
				result.put("success", false);
				result.put("info", "该计划下有待执行的子任务，不能编辑！");
			} else if (DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())) {
				DmTaskStageArg stageArg = new DmTaskStageArg();
				DmTaskStageArg.DmTaskStageCriteria c = stageArg.createCriteria();
				c.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				c.andStateEqualTo(DMSConstant.Status.PENDING.toString());
				if (dmTaskStageDao.selectByArg(stageArg).size() > 0) {
					result.put("success", false);
					result.put("info", "该计划下有任务正在执行，不能编辑！");
				}
			}
		}
		// 判断数据恢复是不是在执行：state为1、2时，不能修改
		DmDataStatePO ddsPO = dmDataStateDao.selectByPrimaryKey(dmPlanId);
		if (Utils.notEmpty(ddsPO)) {
			if (ddsPO.getState() == 1 || ddsPO.getState() == 2) {
				result.put("success", false);
				result.put("info", "该计划下还有正在进行数据恢复的任务，不能编辑！");
			}
		}
		return result;
	}
}
